// Impl

// Local
#include "fboinsgrenderer.h"
#include "simrenderer.h"
#include <btBulletDynamicsCommon.h>

// Ctor
FboInSGRenderer::FboInSGRenderer(QQuickItem *parent) :
    mAlpha(25.0f),
    mBeta(-25.0f),
    mDistance(5.5f),
    QQuickFramebufferObject(parent)
{
    setAcceptedMouseButtons(Qt::AllButtons);

    //QObject::connect(parent, SIGNAL(qmlSignal(QString)), this, SLOT(cppSlot(QString));
}

FboInSGRenderer::~FboInSGRenderer()
{
    qDebug() << "FboInSGRenderer destroyed";
}

// Create renderer
QQuickFramebufferObject::Renderer*
FboInSGRenderer::createRenderer() const
{
    qDebug() << "Renderer being created...";

    return new SimRenderer();
}

// Event handling
void
FboInSGRenderer::mousePressEvent(QMouseEvent * event)
{
    qDebug() << "Mouse pressed";

    mLastMousePosition = event->pos();
    event->accept();
}

void
FboInSGRenderer::wheelEvent(QWheelEvent *event)
{
    qDebug() << "Wheel moved";

    int delta = event->delta();
    if (event->orientation() == Qt::Vertical) {
        if (delta < 0) {
            mDistance *= 1.1;
        } else if (delta > 0) {
            mDistance *= 0.9;
        }

        update();
    }
    event->accept();
}

void
FboInSGRenderer::mouseMoveEvent(QMouseEvent *event)
{
    qDebug() << "Mouse moved";

    int deltaX = event->x() - mLastMousePosition.x();
    int deltaY = event->y() - mLastMousePosition.y();
    if (event->buttons() & Qt::LeftButton) {
        mAlpha += deltaX;

        while (mAlpha < 0) {
            mAlpha += 360;
        }

        while (mAlpha >= 360) {
            mAlpha -= 360;
        }

        mBeta -= deltaY;
        if (mBeta > 90) {
            mBeta = 90;
        }

        if (mBeta < -90) {
            mBeta = -90;
        }

        update();

    }

    mLastMousePosition = event->pos();
    event->accept();

}

bool
FboInSGRenderer::play() const
{
    return true;
}

void
FboInSGRenderer::setPlay(bool arg)
{
    qDebug() << "SetPlay !!";

    btBroadphaseInterface* broadphase = new btDbvtBroadphase();

    btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
	btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);

	btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;

	btDiscreteDynamicsWorld* dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher,broadphase,solver,collisionConfiguration);

	dynamicsWorld->setGravity(btVector3(0,-10,0));


	btCollisionShape* groundShape = new btStaticPlaneShape(btVector3(0,1,0),1);

	btCollisionShape* fallShape = new btSphereShape(1);


	btDefaultMotionState* groundMotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,-1,0)));
	btRigidBody::btRigidBodyConstructionInfo
			groundRigidBodyCI(0,groundMotionState,groundShape,btVector3(0,0,0));
	btRigidBody* groundRigidBody = new btRigidBody(groundRigidBodyCI);
	dynamicsWorld->addRigidBody(groundRigidBody);


	btDefaultMotionState* fallMotionState =
			new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1),btVector3(0,50,0)));
	btScalar mass = 1;
	btVector3 fallInertia(0,0,0);
	fallShape->calculateLocalInertia(mass,fallInertia);
	btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(mass,fallMotionState,fallShape,fallInertia);
	btRigidBody* fallRigidBody = new btRigidBody(fallRigidBodyCI);
	dynamicsWorld->addRigidBody(fallRigidBody);


	for (int i=0 ; i<300 ; i++) {
			dynamicsWorld->stepSimulation(1/60.f,10);

			btTransform trans;
			fallRigidBody->getMotionState()->getWorldTransform(trans);

			qDebug() << "sphere height: " << trans.getOrigin().getY();
	}

	dynamicsWorld->removeRigidBody(fallRigidBody);
	delete fallRigidBody->getMotionState();
	delete fallRigidBody;

	dynamicsWorld->removeRigidBody(groundRigidBody);
	delete groundRigidBody->getMotionState();
	delete groundRigidBody;


	delete fallShape;

	delete groundShape;


	delete dynamicsWorld;
	delete solver;
	delete collisionConfiguration;
	delete dispatcher;
	delete broadphase;


    emit playChanged();
}

